<?php


namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Redis;
use App\Models\TestRedisMysql;


class QueueTestController extends Controller
{

    public function queue_index(){
        
        return view('test/queue_index');
    }
    
    //获取当前redis中前20的key
    public function get_keys(){
        
        $redis = app('redis');
        $keys = $redis->keys('*'); // 获取所有键
        
        //筛选前缀为catchadmin_database_的keys
        $keys = array_filter($keys, function ($key) {
            return strpos($key, 'catchadmin_database_') !== false;
        });

        if ($keys) {
            $res = [
                'code' => 200,
                'msg' => 'success',
                'data' => $keys
            ];
        } else {
            $res = [
                'code' => 400,
                'msg' => 'no keys found',
                'data' => []
            ];
        }
        
        return response()->json($res);
    }
    //laravel延时队列
    public function delay_queue(Request $request){
        $k = $request->input('key');
        $v = $request->input('value');
        $delay = $request->input('delay');
        
        // 调用 Artisan 命令
        $exitCode = Artisan::call('app:queue-daley');
   
        // 返回命令执行结果（可选）
        if ($exitCode===0) {
            return response()->json([
                'code' => 200,
                'msg' => '延时队列发布成功'
            ]);
        } else {
            return response()->json([
                'code' => 400,
                'msg' => '延时队列发布失败'
            ]);
        }
        
    }
    
    //laravel优先级队列
    public function priority_queue(Request $request){
        $k = $request->input('key');
        $v = $request->input('value');
        $priority = $request->input('priority');
        
        // 调用 Artisan 命令
        $exitCode = Artisan::call('app:queue-priority');
   
        // 返回命令执行结果（可选）
        if ($exitCode===0) {
            return response()->json([
                'code' => 200,
                'msg' => '优先级队列发布成功'
            ]);
        } else {
            return response()->json([
                'code' => 400,
                'msg' => '优先级队列发布失败'
            ]);
        }
        
    }

    public function daley_queue_work(){
        /**
         * queue:work 的设计

        *queue:work 是一个守护进程，它会一直运行，直到手动终止
        *（如按下 Ctrl + C）或收到 queue:restart 信号。
        *它不是一次性任务，而是一个持续监听队列的进程。阻塞当前请求

        *当你在代码中调用 Artisan::call('queue:work'); 时，PHP 会等待该命令执行完毕。
        *由于 queue:work 不会自行退出，当前请求会一直挂起，直到 PHP 脚本执行超时
        *（默认超时时间为 30 秒）。超时机制

        *PHP 的 max_execution_time 设置限制了脚本的最长执行时间。
        *如果 queue:work 运行时间超过该限制，PHP 会强制终止脚本，导致请求失败。
         */
        // 调用 Artisan 命令
        //此命令执行会一直在后台运行
        //$exitCode = Artisan::call('queue:work');
        /**
         * 使用 queue:work --once
        *queue:work --once 只会处理一个队列任务，然后立即退出，不会阻塞当前请求。
        *示例：
        *php
        *Artisan::call('queue:work --once');
        *2. 使用 queue:work --stop-when-empty
        *queue:work --stop-when-empty 会处理所有队列任务，直到队列为空后退出。
        *示例：
        *php
        *Artisan::call('queue:work --stop-when-empty');
        */
        //只消费一次测试时命令行操作无问题，
        //页面操作时存在问题，第一次提交无反应，第二次提交才生效
        //$exitCode = Artisan::call('queue:work --once');
        $exitCode = Artisan::call('queue:work',[
            '--queue' => 'daley_queue',
            '--once' => true
        ]);
        // 返回命令执行结果（可选）
        if ($exitCode===0) {
            return response()->json([
                'code' => 200,
                'msg' => '消费任务启动成功'
            ]);
        } else {
            return response()->json([
                'code' => 400,
                'msg' => '消费任务启动失败'
            ]);
        }
    }
    
    public function priority_queue_work(){
        // 调用 Artisan 命令
        //$exitCode = Artisan::call('queue:work --queue=B,A,default');
        $exitCode = Artisan::call('queue:work',[
            '--queue' => 'B,A,default',
            '--stop-when-empty' => true,
        ]);
   
        // 返回命令执行结果（可选）
        if ($exitCode===0) {
            return response()->json([
                'code' => 200,
                'msg' => '消费任务启动成功'
            ]);
        } else {
            return response()->json([
                'code' => 400,
                'msg' => '消费任务启动失败'
            ]);
        }
    }

    //终止消费任务
    public function stop_queue_work(){
        // 调用 Artisan 命令
        $exitCode = Artisan::call('queue:restart');
   
        // 返回命令执行结果（可选）
        if ($exitCode===0) {
            return response()->json([
                'code' => 200,
                'msg' => '消费任务终止成功'
            ]);
        } else {
            return response()->json([
                'code' => 400,
                'msg' => '消费任务终止失败'
            ]);
        }
    }

    
/*-----------------------------set zset应用 start-----------------------------*/
    //加载应用页面
    public function set_zset(){
            
        return view('test/set_zset');
    }

    //set 抽奖入列
    public function add_set(Request $request){
        $k = $request->input('key');
        $v = $request->input('value');
        
        $vs = json_decode($v,true);
        
        $redis = app('redis');
        $addCount = $redis->sadd($k,...$vs);
        
        if($addCount){
            $res =[
                'code' => 200,
                'msg' => 'success',
                'data' => $addCount
            ];
        }else{
            $res =[
                'code' => 400,
                'msg' => 'fail',
                'data' => []
            ];
        }
        
        return response()->json($res);
        
    }

    //数据展示
    public function get_lucyKeys(){
        $redis = app('redis');
        $lucyKeys = $redis->smembers('lucky');
        
        if($lucyKeys){
            $res =[
                'code' => 200,
                'msg' => 'success',
                'data' => $lucyKeys
            ];
        }else{
            $res =[
                'code' => 400,
                'msg' => 'fail',
                'data' => []
            ];
        }
        
        return response()->json($res);
        
    }
    //抽奖
    public function get_lucky(Request $request){
        $redis = app('redis');
        $lucky = $redis->spop('lucky');
        
        if($lucky){
            return response()->json([
                'code' => 200,
                'msg' => 'success',
                'data' => $lucky
            ]);
        } else {
                return response()->json([
                    'code' => 400,
                    'msg' => 'fail',
                    'data' => []
                ]);
            
        }
        
    }

    //zset 排行榜入列
    //添加数据到排行榜
    public function add_zset(Request $request){
        $k = $request->input('key');
        $v = $request->input('value');
        
        /*
            $v = [
            "food" => "30",
            "tom" => "67",
            "hah" => "90"
            ]
        */
        
        $redis = app('redis');   
        //$addCount = $redis->zadd($k,$score,$member);
        
        $data = $v;
        
        $res=$redis->rawCommand('ZADD',$k, ...array_merge(...array_map(function ($member, $score) {
            return [$score, $member];
        }, array_keys($data), array_values($data))));
        
        if($res){
            return response()->json([
                'code' => 200,
                'msg' => 'success',
                'data' => $res
            ]);
        } else {
                return response()->json([
                    'code' => 400,
                    'msg' => 'fail',
                    'data' => []
                ]);
            
        }
        
    }

    //排行榜展示
    public function get_zset(Request $request){
        $k = $request->input('key'); // 默认ranking
        $k = 'ranking';
        $redis = app('redis');
        //展示前10名
        $zset = $redis->zrevrange($k,0,9,['withscores' => true]);
        //$data = array_keys($zset);
        $data = $zset;
        //dd($zset);
        if($data){
            return response()->json([
                'code' => 200,
                'msg' => 'success',
                'data' => $data
            ]);
        }else{
            return response()->json([
                'code' => 400,
                'msg' => 'fail',
                'data' => []
            ]);
        }
    }

/*-----------------------------set zset应用 end-----------------------------*/


/*-----------------------------发布与订阅 publish subscribe  start-----------------------------*/

    //加载页面
    public function pub_sub(){
        
        return view('test/pub_sub');
    }
    //查询当前pub_user频道的订阅者
    public function get_sub_user(){

        
    }

    //订阅user
    public function sub_user(Request $request){
        $num = $request->input('num');
        $redis = app('redis');
        $redis->subscribe(['quickly.user'.$num], function ($redis, $channel, $message) {  
            //echo "订阅频道：{$channel}，消息：{$message}";
            return response()->json([
                'code' => 200,
                'msg' => "订阅频道：{$channel}，消息：{$message}"
            ]);
        });
    }

    /*
    订阅见命令任务文件 app/console/commands/RedisSubscribe.php
    启动命令：php artisan redis:RedisSubscribe
    */
    public function publish_msg(Request $request){
        /*
        $num = $request->input('num');
        $value = $request->input('value');
        */
        $num = '';
        $value = ['name'=>'lee','age'=>'18'];
        //$value = 'It is a my precious!';
        $redis = app('redis');
        $redis->publish('quickly.user'.$num,json_encode($value));
        
        return response()->json([
            'code' => 200,
            'msg' => $value
        ]);
        
        
    }


    public function add_subscribe(){
        
    }


    /*-----------------------------redis与mysql交互 start-----------------------------*/
    //加载页面
    public function redis_mysql(){
        
        return view('test/redis_mysql');
    }

    /*
    use catch;
    create table test_redis_mysql(
        id int(10) unsigned primary key auto_increment,
        nikoname varchar(255) not null,
        age int(10) unsigned not null,
        sexy enum('男','女'),
        hobby varchar(255) not null,
        pet varchar(255) not null,
        created_at varchar(255) default '0000-00-00 00:00:00',
        updated_at varchar(255) default '0000-00-00 00:00:00'
    )engine=innodb default charset=utf8;

    php artisan make:model TestRedisMysql -m
    */
    //添加数据到数据库并存入redis缓存
    public function data_add(Request $request){
        $nikoname = $request->input('nikoname');
        $age = $request->input('age');
        $sexy = $request->input('sexy');
        $hobby = $request->input('hobby');
        $pet = $request->input('pet');
        $created_at = date('Y-m-d H:i:s');
        $updated_at = date('Y-m-d H:i:s');      
        
        $data = [
            'nikoname' => $nikoname,
            'age' => $age,
            'sexy' => $sexy,
            'hobby' => $hobby,
            'pet' => $pet,
            'created_at' => $created_at,
            'updated_at' => $updated_at
        ];
        $model = new TestRedisMysql();
        $model->nikoname = $nikoname;
        $model->age = $age;
        $model->sexy = $sexy;
        $model->hobby = $hobby;
        $model->pet = $pet;
        $model ->save();
        
        if($model->id){
            $data['id'] = $model->id;
            $redis = app('redis');
            $redis->hmset('test_redis_mysql:user:'.$model->id,$data);
            
            return response()->json([
                'code' => 200,
                'msg' => 'success',
            ]);
        } else {
            return response()->json([
                'code' => 400,
                'msg' => 'fail'
            ]);
        }

    }

    //数据查询
    public function getRedisMYsql(Request $request){
        $id = $request->input('id');
    
        $redis = app('redis');
        $data = $redis->hgetall('test_redis_mysql:user:'.$id);

        //如果redis缓存中未查询到则直接从数据库中查询,并加入redis缓存
        if(empty($data)){

            $data = $this->get_mysql_data($id);
            
            //dd(json_decode($data[0],true));
            $data = json_decode($data[0],true);
            //加入redis缓存
            $redis->hmset('test_redis_mysql:user:'.$id,$data);
            //设置缓存时间
            $redis->expire('test_redis_mysql:user:'.$id,60);
            
        }
        
        if($data){
            return response()->json([
                'code' => 200,
                'msg' => 'success',
                'data' => $data
            ]);
        }else {
            return response()->json([
                'code' => 400,
                'msg' => 'fail',
                'data' => []
            ]);
        }
    }
    
    //直接从数据库中获取
    public function get_mysql_data($parm){
        return $data = TestRedisMysql::where('id',$parm)->get();
    }

/*-----------------------------redis与mysql交互 end-----------------------------*/


    
}